home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #
- # (c) Copyright 2003-2008 Hewlett-Packard Development Company, L.P.
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- #
- # Author: Don Welch
- #
-
- __version__ = '0.1'
- __title__ = "Services and Status System Tray Device I/O Child Process"
- __mod__ = 'hpdio'
- __doc__ = "Provides device I/O process isolation for system tray application."
-
-
- # StdLib
- import sys
- import struct
- import os
- import time
- import Queue
- import select
- from cPickle import dumps, HIGHEST_PROTOCOL
-
- # Local
- from base.g import *
- from base.codes import *
- from base import utils, device, status, models
-
- # dBus
- try:
- from dbus import lowlevel, SessionBus
- except ImportError:
- log.error("dbus failed to load (python-dbus ver. 0.80+ required). Exiting...")
- sys.exit(1)
-
- # Globals
- PIPE_BUF = 4096
- session_bus = None
- r2, w3 = None, None
- devices = {} # { 'device_uri' : device.Device(), ... }
-
-
- def send_message(device_uri, event_code, bytes_written=0):
- args = [device_uri, '', event_code, prop.username, 0, '', '', bytes_written]
- msg = lowlevel.SignalMessage('/', 'com.hplip.StatusService', 'Event')
- msg.append(signature='ssisissi', *args)
- SessionBus().send_message(msg)
-
-
- def run(read_pipe2=None, # pipe from hpssd
- write_pipe3=None): # pipe to hpssd
-
- global r2, w3
- tmp_dir = '/tmp'
- os.umask(0111)
-
- try:
- log.set_module("hp-systray(hpdio)")
- log.debug("PID=%d" % os.getpid())
-
- r2, w3 = read_pipe2, write_pipe3
-
- fmt = "64s64sI32sI64sf" # TODO: Move to Event class
- fmt_size = struct.calcsize(fmt)
-
- response = {}
- dev = None
- m = ''
- while True:
- try:
- r, w, e = select.select([r2], [], [r2], 1.0)
- except KeyboardInterrupt:
- break
- except select.error, e:
- if e[0] == errno.EINTR:
- continue
- else:
- break
-
- if not r: continue
- if e: break
-
- m = ''.join([m, os.read(r2, fmt_size)])
-
- if not m:
- break
-
- while len(m) >= fmt_size:
- response.clear()
- event = device.Event(*struct.unpack(fmt, m[:fmt_size]))
- m = m[fmt_size:]
-
- action = event.event_code
- device_uri = event.device_uri
-
- log.debug("Handling event...")
- event.debug()
-
- send_message(device_uri, EVENT_DEVICE_UPDATE_ACTIVE)
-
- if action in (EVENT_DEVICE_UPDATE_REQUESTED, EVENT_POLLING_REQUEST):
- #try:
- if 1:
- #log.debug("%s starting for %s" % (ACTION_NAMES[action], device_uri))
-
- try:
- dev = devices[device_uri]
- except KeyError:
- dev = devices[device_uri] = device.Device(device_uri, disable_dbus=True)
-
- try:
- #print "Device.open()"
- dev.open()
- except Error, e:
- log.error(e.msg)
- response = {'error-state': ERROR_STATE_ERROR,
- 'device-state': DEVICE_STATE_NOT_FOUND,
- 'status-code' : EVENT_ERROR_DEVICE_IO_ERROR}
-
- if dev.device_state == DEVICE_STATE_NOT_FOUND:
- dev.error_state = ERROR_STATE_ERROR
- else:
- if action == EVENT_DEVICE_UPDATE_REQUESTED:
- try:
- #print "Device.queryDevice()"
- dev.queryDevice()
-
- except Error, e:
- log.error("Query device error (%s)." % e.msg)
- dev.error_state = ERROR_STATE_ERROR
- dev.status_code = EVENT_ERROR_DEVICE_IO_ERROR
-
- response = dev.dq
- #print response
-
- log.debug("Device state = %d" % dev.device_state)
- log.debug("Status code = %d" % dev.status_code)
- log.debug("Error state = %d" % dev.error_state)
-
- else: # EVENT_POLLING_REQUEST
- try:
- dev.pollDevice()
-
- except Error, e:
- log.error("Poll device error (%s)." % e.msg)
- dev.error_state = ERROR_STATE_ERROR
-
- else:
- response = {'test' : 1}
-
- #finally:
- if 1:
- if dev is not None:
- dev.close()
-
- #thread_activity_lock.release()
-
- elif action == EVENT_USER_CONFIGURATION_CHANGED:
- pass
-
- elif action == EVENT_SYSTEMTRAY_EXIT:
- log.debug("Exiting")
- sys.exit(1)
-
- send_message(device_uri, EVENT_DEVICE_UPDATE_INACTIVE)
-
- if action == EVENT_DEVICE_UPDATE_REQUESTED:
- #print response
- data = dumps(response, HIGHEST_PROTOCOL)
-
- log.debug("Sending data through pipe to hpssd...")
- total_written = 0
- while True:
- total_written += os.write(w3, data[:PIPE_BUF])
- data = data[PIPE_BUF:]
- if not data:
- break
-
- log.debug("Wrote %d bytes" % total_written)
-
- send_message(device_uri, EVENT_DEVICE_UPDATE_REPLY, total_written)
-
- elif action == EVENT_POLLING_REQUEST:
- # TODO: Translate into event: scan requested, copy requested, etc.. send as event
- #try:
- # os.write
- pass
-
-
- except KeyboardInterrupt:
- log.debug("Ctrl-C: Exiting...")
-